﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;

namespace Xodeuz.SP.Common
{
    public static class ListExtensions
    {
        /// <summary>
        /// Returns a collection of items from the specified query, cast to desired object
        /// </summary>
        public static List<T> GetItems<T>(this SPList list, SPQuery query) where T : new()
        {
            var items = list.GetItems(query);
            return ListItemReflector.CastTo<T>(items);
        }

        /// <summary>
        /// Returns the item with the specified integer ID
        /// </summary>
        public static T GetItemById<T>(this SPList list, int id) where T : new()
        {
            SPListItem item = list.GetItemById(id);
            return ListItemReflector.CastTo<T>(item);
        }

        /// <summary>
        /// Delete SPListItem by ItemID
        /// </summary>
        /// <param name="list"></param>
        /// <param name="collection"></param>
        public static void DeleteItemById(this SPList list, ListItemModelBase baseModel)
        {
            list.Items.DeleteItemById(baseModel.ItemId);
        }

        /// <summary>
        /// Quick remove large number of items
        /// </summary>
        /// <param name="list"></param>
        /// <param name="collection"></param>
        public static void DeleteItems(this SPList list, List<ListItemModelBase> collection)
        {
            var deletionXml = BatchXmlCreator.CreateDeletionXml(collection.Select(x => x.ItemId).ToList(), list.ID);
            list.ParentWeb.ProcessBatchData(deletionXml);
        }

        /// <summary>
        /// Quick remove large number of items
        /// </summary>
        /// <param name="list"></param>
        /// <param name="collection"></param>
        public static void DeleteItems(this SPList list, List<int> collection)
        {
            var deletionXml = BatchXmlCreator.CreateDeletionXml(collection, list.ID);
            list.ParentWeb.ProcessBatchData(deletionXml);
        }

        /// <summary>
        /// Add a number of items to the desired list
        /// </summary>
        public static void CreateItems<T>(this SPList list, List<T> collection)
        {
            var batches = BatchXmlCreator.CreateItemsXml(collection,list.ID);
            foreach (var batch in batches)
            {
                list.ParentWeb.ProcessBatchData(batch);
            }
        }

        /// <summary>
        /// Query for gathering large amount of data in batches (2000 items per batch)
        /// </summary>
        public static List<SPListItem> LargeListQuery(this SPList list, SPQuery query)
        {
            List<SPListItem> resultsList = new List<SPListItem>();
            query.RowLimit = 2000;
            query.QueryThrottleMode = SPQueryThrottleOption.Default;

            do
            {
                var result = list.GetItems(query);

                resultsList.AddRange(result.Cast<SPListItem>());

                query.ListItemCollectionPosition = result.ListItemCollectionPosition;
            }
            while (query.ListItemCollectionPosition != null) ;

            return resultsList;
        }

        /// <summary>
        /// Query for gathering large amount of data in batches (2000 items per batch)
        /// </summary>
        public static List<T> LargeListQuery<T>(this SPList list, SPQuery query) where T : new()
        {
            List<T> resultsList = new List<T>();
            query.RowLimit = 2000;
            query.QueryThrottleMode = SPQueryThrottleOption.Default;

            do
            {
                var result = list.GetItems(query);

                resultsList.AddRange(ListItemReflector.CastTo<T>(result));

                query.ListItemCollectionPosition = result.ListItemCollectionPosition;
            }
            while (query.ListItemCollectionPosition != null);

            return resultsList;
        }

      }
}
